package com.atguigu.yygh.hosp.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.yygh.cmn.client.DictFeignClient;
import com.atguigu.yygh.common.handler.YyghException;
import com.atguigu.yygh.enums.DictEnum;
import com.atguigu.yygh.hosp.repository.HospitalRepository;
import com.atguigu.yygh.hosp.service.HospitalService;
import com.atguigu.yygh.model.hosp.BookingRule;
import com.atguigu.yygh.model.hosp.Hospital;
import com.atguigu.yygh.vo.hosp.HospitalQueryVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class HospitalServiceImpl implements HospitalService {
    @Autowired
    private HospitalRepository hospitalRepository;

    //调用远程接口DictFeignClient
    @Autowired
    private DictFeignClient dictFeignClient;

    /**
     * 上传医院信息
     *
     * @param paramMap
     */
    @Override
    public void saveHospital(Map<String, Object> paramMap) {
        //1.参数转型  paramMap==》saveHospital ， Map转成Hospital
        //  借用JSONObject工具转型：
        String jsonString = JSONObject.toJSONString(paramMap);
        //  再次转换成对象：
        Hospital hospital = JSONObject.parseObject(jsonString, Hospital.class);
        //2.跟据 hoscode 医院编码(唯一)查询医院信息
        //  查询数据库返回的信息：
        Hospital targetHospital = hospitalRepository.getByHoscode(hospital.getHoscode());
        //3.判断信息是否查询到，
        if (targetHospital != null) {
            //3.1 查询到医院信息，更新数据                               更新的字段
            hospital.setId(targetHospital.getId());                  // 主键id
            hospital.setCreateTime(targetHospital.getCreateTime());  // 创建时间
            hospital.setUpdateTime(new Date());                      // 修改时间（传入一个当前系统时间）
            hospital.setIsDeleted(targetHospital.getIsDeleted());    // 逻辑删除
//            hospital.setLogoData(targetHospital.getLogoData());  //logo
            hospital.setStatus(targetHospital.getStatus());          // 状态值
            //  保存更新入库：
            hospitalRepository.save(hospital);
        } else {
            //3.2 查询失败，医院信息为空，新增数据
            hospital.setCreateTime(new Date()); //此时查询不到数据，因此没有值，如果还继续打点调用getCreateTime则空指针行为。
            hospital.setUpdateTime(new Date());
            hospital.setIsDeleted(0);       //没有给一个默认值
            hospital.setStatus(0);          //没有给一个默认值
            //  保存数据：
            hospitalRepository.save(hospital);
        }
    }

    /**
     * 根据hoscode查询查询医院信息
     *
     * @param hoscode
     * @return
     */
    @Override
    public Hospital getHospByHoscode(String hoscode) {
//        return hospitalRepository.getHospitalByHoscode(hoscode);
        Hospital hospital = hospitalRepository.getByHoscode(hoscode);
        if(hospital==null){
            throw new YyghException(20001,"医院信息有误");
        }
        return hospital;
    }

    /**
     * 查询医院列表 - 带条件带分页
     * @param page            当前页码
     * @param limit           每页记录数
     * @param hospitalQueryVo 查询条件
     */
    @Override
    public Page<Hospital> selectPage(Integer page,
                                     Integer limit,
                                     HospitalQueryVo hospitalQueryVo) {
        //1.创建分页对象
        //  1.1创建排序对象
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        //  1.2创建分页对象
        Pageable pageable = PageRequest.of((page - 1), limit, sort);
        //2.创建条件模板
        //  2.1封装查询条件（对象）
        Hospital hospital = new Hospital();
        BeanUtils.copyProperties(hospitalQueryVo, hospital);
        //  2.2创建模板构造器
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
                .withIgnoreCase(true);
        //  2.3创建条件模板
        Example<Hospital> example = Example.of(hospital, matcher);
        //3.带条件带分页的查询
        Page<Hospital> pageModel = hospitalRepository.findAll(example, pageable);
        //4. 从分页对象获取集合，遍历集合，翻译字段（跨模块）
        pageModel.getContent().forEach(item -> {
            //翻译字段
            this.packHospital(item);
        });
        return pageModel;
    }

    /**
     * 更新上线状态
     *
     * @param id
     * @param status
     */
    @Override
    public void updateStatus(String id, Integer status) {
        if (status.intValue() == 0 || status.intValue() == 1) { //intValue 数据转型  0=未上线 1=已上线
            Hospital hospital = hospitalRepository.findById(id).get();//获取相关数据
            hospital.setStatus(status);//状态值
            hospital.setUpdateTime(new Date());//时间
            hospitalRepository.save(hospital);//入库，完成数据更新
        }
    }

    /**
     * 获取医院详情
     *
     * @param id
     */
    @Override
    public Map<String, Object> show(String id) {
        //1、跟据id查询医院信息，翻译字段
        Hospital hospital = this.packHospital(hospitalRepository.findById(id).get());
        //2、从医院信息中 取出预约规则，清空内存中的重复数据(预约规则)
        BookingRule bookingRule = hospital.getBookingRule();  //单独处理更直观
        hospital.setBookingRule(null);//不需要重复返回
        //3、封装数据返回
        Map<String, Object> map = new HashMap<>();
        map.put("hospital", hospital);  //医院基本信息（包含医院等级）
        map.put("bookingRule", bookingRule);
        return map;
    }

    /**
     * 医院管理展示多条数据分页用
     *
     * @param page
     * @param limit
     * @param hospitalQueryVo
     * @return
     */
    @Override
    public Page<Hospital> selectPageForShow(int page, int limit, HospitalQueryVo hospitalQueryVo) {
        return null;
    }

    /**  2023-03-03 14:34:14
     * 获取医院名称
     * @param hoscode
     */
    @Override
    public String getHospName(String hoscode) {
        Hospital hospital = this.getHospByHoscode(hoscode);//调用之前写的方法，根据hoscode查询查询医院信息
        return hospital.getHosname();
    }

    /** 2023-03-04 11:20:53
     * 根据医院名称获取医院列表（模糊查询）
     * @param hosname 医院名称
     * @return
     */
    @Override
    public List<Hospital> findByHosnameList(String hosname) {
        List<Hospital> list = hospitalRepository.getByHosnameLike(hosname);//Like模糊查询
        return list;
    }

    /**  2023-03-04 15:41:38
     * 医院预约挂号详情 - 跟据医院编码获取医院相关信息
     * @param hoscode 医院编码
     * @return
     */
    @Override
    public Map<String, Object> getHsopInfo(String hoscode) {
        //1、跟据id查询医院信息，翻译字段
        Hospital hospital =
                this.packHospital( //②翻译字段，已经存在的方法
                hospitalRepository.getByHoscode(hoscode)//①查询医院信息
        );
        //2、从医院信息中 取出预约规则，清空内存中的重复数据(预约规则)
        BookingRule bookingRule = hospital.getBookingRule();  //单独处理更直观
        hospital.setBookingRule(null);//不需要重复返回
        //3、封装数据返回
        Map<String, Object> map = new HashMap<>();
        map.put("hospital", hospital);  //医院基本信息（包含医院等级）
        map.put("bookingRule", bookingRule);
        return map;
    }

    /**
     * 翻译字段 封装数据
     * @param hospital 医院
     */
    private Hospital packHospital(Hospital hospital) {
        //调用远程接口DictFeignClient
        //翻译医院等级
        String hostypeString = dictFeignClient.getName(
              //DictEnum枚举类
                DictEnum.HOSTYPE.getDictCode(), hospital.getHostype());
        //翻译国标数据
        String provinceString = dictFeignClient.getName(hospital.getProvinceCode());//省份
        String cityString = dictFeignClient.getName(hospital.getCityCode());//城市
        String districtString = dictFeignClient.getName(hospital.getDistrictCode());//地区

        //封装数据
        hospital.getParam().put("hostypeString", hostypeString);
        hospital.getParam().put("fullAddress", provinceString + cityString + districtString + hospital.getAddress());
        return hospital;
    }


}
